#include <stdio.h>
#include <string.h>
#include <sys/time.h>

#define SPACE 's'
#define RED 'r'
#define BLUE 'b'
#define GREEN 'g'

// Flag vector to signal the end of the wins in the wins array
#define END_OF_WINS 0	

int columns;
int rows;
// NOTE: last_move starts at 1, not 0. This happens to be beneficial because, with padding, the first column is board[1]
int last_move;
int total_time;
int player_1_time;
int last_move_time;


// The Wins Lookup Table
char WINS_LOOKUP[12][4] = {"ggrr","grgr","rgrg","rrgg","grrg","rggr","ggbb","gbgb","bgbg","bbgg","gbbg","bggb"};

int win_lookup[2000] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,3,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,0,0,0,0,0,0,0,0,0,0,-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};


FILE *f;
FILE *w;




// Print Board function for debugging
void printBoard(char board[columns+2][rows+2])
{
	#if DEBUG
	int i, j;
	// TEST: Print out board
	for (i = 0; i < rows+2; i++)
	{
		fprintf(f, "\t");
		for (j = 0; j < columns+2; j++)
		{
			fprintf(f, "%c ", board[j][i]);
		}
		fprintf(f, "\n");
	}
	fprintf(f, "\n");
	#endif
}

void findWins(char board[columns+2][rows+2], char wins[150][4])
{
	// last_piece_x and last_piece_y hold co-ordinates of the last played piece, that is the piece that must be checked for wins
	int last_piece_x = last_move, last_piece_y, winIndex = 0;
	int i;
	// get the last piece's Y co-ordinate
	for (i=1;i<rows+1;i++)
	{
		if(board[last_piece_x][i] == SPACE)
			break;
		 last_piece_y = i;
	}
	
	//printf("Last Moved Piece's co-ordinates:%i, %i, %c\n", last_piece_x, last_piece_y, board[last_piece_x][last_piece_y]);	
		
	/*
	 * How this works is: For each directional axis (X, Y, Diagonal Down Left-to-Right, and Diagonal Up Left-to-Right), the last dropped
	 * piece can be in 4 vectors (it can be in positions 0-3). For each of these possible positions, the algorithm grabs the 4 pieces
	 * and then checks that vector to see if it is a win. If so, it adds it to the wins array.
	*/
	
	// Diagonal Top Left<->Bottom Right
	//printf("Beginning Diagonal Loop\n");
	for(i=0;i<4;i++) // Check each of the 4 possible positions for the last dropped piece
	{
		short int offset, size = 1;

		//printf("for position:%i\n", i);

		// The co-ordinates used to build the vector to check on. Note these move diagonally to the right,down.
		short int start_piece_x = last_piece_x + i, start_piece_y = last_piece_y - i;
		//printf("start_piece co-ordinates are: %i, %i\n", start_piece_x, start_piece_y);
		// If the starting piece is a space, stop moving in that direction
		if (board[start_piece_x][start_piece_y] == SPACE)
		{
			//printf("BREAK1: Found Space, finished looking at diagonal!\n", i);
			break;
		}

		char win[4] = {board[start_piece_x][start_piece_y],'s','s','s'};
		// Build a vector going diagonally to the up, left
		for (offset = 1;offset < 4;offset++)
		{
			if (board[start_piece_x-offset][start_piece_y+offset] == SPACE)
			{
				//printf("BREAK2: Found Space While building a vector\n");
				break;
			}	
			win[size++] = board[start_piece_x-offset][start_piece_y+offset];
		}
		if (size == 4) // Found a four piece vector (No Spaces)
		{
			//printf("Successfully Found a Four-Piece Vector: %s\n", win);
			int k;
			for (k=0;k<12;k++)
			{
				if (strncmp(win,WINS_LOOKUP[k], 4) == 0)
				{
					//printf("Found a Win! Vector is %s\n", win);
					strcpy(wins[winIndex++], win);
				}
			}
			
		}
	}
	// Top<->Bottom
	//printf("Beginning Vertical Loop\n");
	for(i=0;i<4;i++)
	{
		short int offset, size = 1;
		//printf("for position:%i\n", i);
		short int start_piece_x = last_piece_x, start_piece_y = last_piece_y - i;
		//printf("start_piece co-ordinates are: %i, %i\n", start_piece_x, start_piece_y);
		if (board[start_piece_x][start_piece_y] == SPACE)
		{
			//printf("BREAK1: Found Space, finished looking at Vertical!\n", i);
			break;
		}

		char win[4] = {board[start_piece_x][start_piece_y],'s','s','s'};
		// Build a vector going diagonally to the up, left
		for (offset = 1;offset < 4;offset++)
		{
			if (board[start_piece_x][start_piece_y+offset] == SPACE)
			{
				//printf("BREAK2: Found Space While building a vector\n");
				break;
			}
			win[size++] = board[start_piece_x][start_piece_y+offset];
		}
		if (size == 4) // Found a four piece vector (No Spaces)
		{
			//printf("Successfully Found a Four-Piece Vector: %s\n", win);
			int k;
			for (k=0;k<12;k++)
			{
				if (strncmp(win,WINS_LOOKUP[k], 4) == 0)
				{
					//printf("Found a Win! Vector is %s\n", win);
					strcpy(wins[winIndex++], win);
				}
			}
			
		}
	}
	// Diagonal Bottom Left<->Top Right
	//printf("Beginning 2nd Diagonal Loop\n");
	for(i=0;i<4;i++)
	{
		short int offset, size = 1;
		//printf("for position:%i\n", i);

		short int start_piece_x = last_piece_x - i, start_piece_y = last_piece_y - i;
		//printf("start_piece co-ordinates are: %i, %i\n", start_piece_x, start_piece_y);
		if (board[start_piece_x][start_piece_y] == SPACE)
		{
			//printf("BREAK1: Found Space, finished looking at 2nd diagonal!\n", i);
			break;
		}

		char win[4] = {board[start_piece_x][start_piece_y],'s','s','s'};
		// Build a vector going diagonally to the up, left
		for (offset = 1;offset < 4;offset++)
		{
			if (board[start_piece_x+offset][start_piece_y+offset] == SPACE)
			{
				//printf("BREAK2: Found Space While building a vector\n");
				break;
			}
				
			win[size++] = board[start_piece_x+offset][start_piece_y+offset];
		}
		if (size == 4) // Found a four piece vector (No Spaces)
		{
			//printf("Successfully Found a Four-Piece Vector: %s\n", win);
			int k;
			for (k=0;k<12;k++)
			{
				if (strncmp(win,WINS_LOOKUP[k], 4) == 0)
				{
					//printf("Found a Win! Vector is %s\n", win);
					strcpy(wins[winIndex++], win);
				}
			}
			
		}
	}
	//  Left<->Right
	//printf("Beginning Horizontal Loop\n");
	for(i=0;i<4;i++)
	{
		short int offset, size = 1;
		//printf("for position:%i\n", i);

		short int start_piece_x = last_piece_x - i, start_piece_y = last_piece_y;
		//printf("start_piece co-ordinates are: %i, %i\n", start_piece_x, start_piece_y);
		if (board[start_piece_x][start_piece_y] == SPACE)
		{
			//printf("BREAK1: Found Space, finished looking at Horizontal!\n", i);
			break;
		}

		char win[4] = {board[start_piece_x][start_piece_y],'s','s','s'};
		// Build a vector going diagonally to the up, left
		for (offset = 1;offset < 4;offset++)
		{
			if (board[start_piece_x+offset][start_piece_y] == SPACE)
			{
				//printf("BREAK2: Found Space While building a vector\n");
				break;
			}
				
			win[size++] = board[start_piece_x+offset][start_piece_y];
		}
		if (size == 4) // Found a four piece vector (No Spaces)
		{
			//printf("Successfully Found a Four-Piece Vector: %s\n", win);
			int k;
			for (k=0;k<12;k++)
			{
				if (strncmp(win,WINS_LOOKUP[k], 4) == 0)
				{
					//printf("Found a Win! Vector is %s\n", win);
					strcpy(wins[winIndex++], win);
				}
			}
			
		}
	}
	// End with "end of wins" flag vector, to signal the end of wins
	wins[winIndex][0] = END_OF_WINS;
}


int checkCol(char board[columns+2][rows+2], int col)
{  
	int i = 0;
	
	if(board[col][rows] != SPACE)
		return 0;//if the top of the col isn't a space - it is full
	else
		for(i = rows-1; i > 0; i--)
		{
			if(board[col][i] == SPACE)
				continue;
			else
				return i+1;
		}
		return i+1;
}


int getWins(char board[columns+2][rows+2], int col)
{
	int i = 0;
	int m = 0;
	int n = 0;
	int row = 0;
	int score  = 0;
	int x[7] = {col-3, col-2, col -1, col, col+1, col+2, col+3};	

	if((row = checkCol(board, col)) == 0)
		return 0;//col is full
	int y[7] = {row-3, row-2, row-1, row, row+1, row+2, row+3};
	
	for(m = 0; m <= 3; m++)
	{
		if(x[m] < 1 || x[m+3] > columns)//out of bounds - not on board
			continue;
		
		
		score = win_lookup[ (board[x[m]][row] << 3) + (board[x[m+1]][row] << 2) + (board[x[m+2]][row] << 1) + (board[x[m+3]][row])];
		fprintf(w, "\t\tTrying: %c,%c,%c,%c -> %d points\n", board[x[m]][row],  board[x[m+1]][row], board[x[m+2]][row],  board[x[m+3]][row], score);
		if(score)
			return score;
		for(n = 0; n <= 3; n++)
		{
			if(y[n] < 1 || y[n+3] > rows)//looking off board, don't do it
				continue;
			
			score = win_lookup[(board[x[m]][y[n]] << 3) + (board[x[m+1]][y[n+1]] << 2) + (board[x[m+2]][y[n+2]] << 1) + (board[x[m+3]][y[n+3]])];//diag up rightif(score)
			fprintf(w, "\t\tTrying: %c,%c,%c,%c -> %d points\n", board[x[m]][y[n]],  board[x[m+1]][y[n+1]], board[x[m+2]][y[n+2]],  board[x[m+3]][y[n+3]], score);
			if(score)
				return score;
			score = win_lookup[(board[x[m]][y[n+3]] << 3) + (board[x[m+1]][y[n+2]] << 2) + (board[x[m+2]][y[n+1]] << 1) + (board[x[m+3]][y[n]])];//diag down right
			fprintf(w, "\t\tTrying: %c,%c,%c,%c -> %d points\n",board[x[m]][y[n+3]],  board[x[m+1]][y[n+2]],  board[x[m+2]][y[n+1]] ,  board[x[m+3]][y[n]], score);
			if(score)
				return score;
			score = win_lookup[(board[col][y[n]] << 3) + (board[col][y[n+1]] << 2) + (board[col][y[n+2]] << 1) + (board[col][y[n+3]])];//up-down
			fprintf(w, "\t\tTrying: %c,%c,%c,%c -> %d points\n", board[col][y[n]],  board[col][y[n+1]],  board[col][y[n+2]],  board[col][y[n+3]], score);
			if(score)
				return score;
			
		}
	}
	#if DEBUG
	//fprintf(f, "guess returns %d in column %d\n", score, col);
	#endif
	return score;
}



int main( int argc, char **argv)
{
	int i, j;
	char board[10][9];
	char buf[128];
	f = fopen("testboards.txt", "r");
	w = fopen("isWinTestOutput.txt", "w");
	int points = 0;
	int points2 = 0;
	char value[8];
	int count = 0;
	int score = 0;
	
	do{
		count++;
		//printf("opened");
		fscanf(f, "(%d,%d,%d,%d,%d,%d", &columns, &rows, &last_move, &total_time, &player_1_time, &last_move_time);
		
		// Populate board array
		for (i = 0; i < columns+2; i++)
		{
			// Padding columns on left and right sides of board
			if (i == 0 || i == columns+1)
			{
				for(j = 0; j < rows+2; j++)
					board[i][j] = SPACE;
				continue;
			}
			// Padding Row over bottom of board
			board[i][0] = SPACE;
			for (j = 1; j < rows+1; j++)
			{
				fscanf(f,",%c", &board[i][j]);
			}
			// Padding row over top of board
			board[i][j] = SPACE;
		}
		printf("\n");
		fgetc(f);
		fgetc(f);//get the space - leave it out
		
		i = 0;
		value[i] = fgetc(f);//get first char
		//printf("value is: %c\n", value[i]);
		
		if(value[i] == '-')//if it is a negative sign, get the next one
		{
			i++;
			value[i] = fgetc(f);//get second char
			//printf("value is:%c\n", value[i]);
			i++;
			value[i] = '\0';//mark the end
			points = ('0' - value[1]);
			
		}
		
		else
		{
			value[1] = '\0';//mark the end
			points = 0 - ('0' - value[0]);
			
		}
		
		//printf("\n\n***** %d\n\n", points);
		
		//get the rest of the line and do nothing with it. Should only be a few bytes for the value of the win
		fgets(buf, 127, f); 
		
		// How many possible simultaneous wins can there be?
		char wins[150][4];
		findWins(board, wins);
		fprinf(w, "last Played: %d", last_move);
		printBoard(board);
		
		points2 = getWins(board, last_move);
		score = win_lookup[ (wins[0][0] << 3) + (wins[0][1] << 2) + (wins[0][2] << 1) + (wins[0][3])];
		fprintf(w, "Vector: %c,%c,%c,%c -> %d points\n", wins[0][0],  wins[0][1],  wins[0][2],  wins[0][3], score);
		if(points == points2)
			fprintf(w, "Case: %d: PASS -> %d = %d\n",count, points, points2);
		else
			fprintf(w, "\n\nCase: %d: **************   FAIL %d != %d   ****************\n\n",count, points, points2);

	}while(!feof(f));
	fclose(f);
	


	
}

